"""
此文件主要为统一接口返回类型
以及提供必要的数据类型转换工具类
"""
import hmac
import json
from datetime import datetime
from hashlib import md5
from bson import ObjectId
from mongoengine.base import BaseDocument


class CodeModeDTO:
    """
    code message data类型的接口返回工具类
    辅助构建符合CodeMode的返回值以及提供转化为json的方法
    """

    # 成功
    SUCCESS = 0
    # 系统内部错误
    SYSTEM_ERROR = -1
    # 参数错误
    PARAMETER_ERROR = 1

    def __init__(self, code, message, data):
        """
        构造方法，使对象在构造时满足必须参数
        :param code: int 返回码
        :param message: string 返回消息
        :param data: obj 返回的数据
        """
        self.code = code
        self.message = message
        self.data = data

    def to_json(self):
        """
        类内参数转化为json数据，方便接口返回传递
        :return: json数据
        """
        result_dict = {"code": self.code, "message": self.message, "data": self.data}
        return json.dumps(result_dict, ensure_ascii=False)


def query_set_to_list(query_set):
    """
    QuerySet转化为列表
    :param query_set: 从数据库获取的查询集合
    :return: 列表数据
    """
    # 返回的列表
    return_list = []
    # 转化实体列表
    model_list = list(query_set)
    # 实体转化为字典
    for model in model_list:
        return_list.append(model_to_dict(model))
    return return_list


def model_to_dict(model):
    """
    转化实体为字典
    :param model: 从数据查询出来的数据实体
    :return: 字典
    """
    # 返回的字典
    return_dict = {}
    # 提取Key值列表
    key_list = list(model)
    # 插入字典
    for k in key_list:
        # 字符串类型识别
        if isinstance(model[k], str):
            return_dict[k] = model[k]
        # ObjectId类型识别
        elif isinstance(model[k], ObjectId):
            return_dict[k] = str(model[k])
        # 当类型识别为datetime时
        elif isinstance(model[k], datetime):
            return_dict[k] = str(model[k])
        # 继承自list说明数据库类型Array
        # 调用父级转换
        elif isinstance(model[k], list):
            return_dict[k] = query_set_to_list(model[k])
        # 内嵌文档
        # 递归调用
        elif isinstance(model[k], BaseDocument):
            return_dict[k] = model_to_dict(model[k])
        else:
            return_dict[k] = model[k]
    return return_dict


def sort_dict(record_dict):
    """
    字典排序算法
    :param record_dict:
    :return:
    """
    # after = sorted(record_dict.items())
    after = sorted(record_dict.keys())
    return after


def encrypt(signature1, secretkey):
    """
    加密算法（该项目没用上）
    :param signature1: 要加密的
    :param secretkey: 密钥
    :return: 签名
    """
    signature = bytes(signature1, encoding='utf-8')
    secretkey = bytes(secretkey, encoding='utf-8')
    # 这里python跟其他语言的写法不太一样。密钥在第一位，第二位才是要加密的。而且是bytes类型加密
    sign = hmac.new(secretkey, signature, md5).digest()
    return sign
